#ifndef YHAIDA_MUTEX_H
#define YHAIDA_MUTEX_H
#include <pthread.h>
#include <assert.h>
#include <stdio.h>
#include "../base/Utils.h"

/*
    虽然c++11有std::mutex,但是封装一个mutex带tid
*/
namespace yhaida
{
    class MutexLock : Utils::nocapyable
    {
    public:
        MutexLock() : _holderPid(0)
        {
            if (pthread_mutex_init(&_mutex, NULL))
            {
                printf("mutex init is wrong");
            }
        }
        ~MutexLock()
        {
            assert(_holderPid == 0);
            pthread_mutex_destroy(&_mutex);
        }
        //加锁
        void lock()
        {
            pthread_mutex_lock(&_mutex);
            _holderPid = CurrentThread::tid();
        }
        //解锁
        void unlock()
        {
            _holderPid = 0;
            pthread_mutex_unlock(&_mutex);
        }
        //获取锁配合条件变量
        pthread_mutex_t *getPthreadMutex()
        {
            return &_mutex;
        }

        bool isLockedByThisThread()
        {
            return _holderPid == CurrentThread::tid();
        }

    private:
        pthread_mutex_t _mutex;
        pid_t _holderPid;
    };

    class MutexLockGuard : Utils::nocapyable
    {
    public:
        explicit MutexLockGuard(MutexLock &m) : _mutex(m)
        {
            _mutex.lock();
        }
        ~MutexLockGuard()
        {
            _mutex.unlock();
        }

    private:
        MutexLock &_mutex;
    };
//正确的写法是 MutexLockGuard(MutexLock) guard;
#define MutexLockGuard(x) error "Missing guard object name"
}
#endif
